home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / asm / games / readkeys / advanced_readkey.s
Text File  |  1980-01-03  |  5KB  |  192 lines

  1. *******************************************************************************
  2. * Amiga MC680x0 Hardware "Read-Keyboard" Interrupt Handler
  3. * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  4. * This source provides a nice and easy way of polling the Amiga keyboard from
  5. * a hardware environment. The OS *must* be disabled in order to use this code!
  6. * Use this for games, demo`s and the like.
  7. *
  8. * The nice thing about the routine is that it supports Keyboard Qualifiers, not
  9. * many hardware keyboard handlers I have seen in the past do this! Also this
  10. * routine uses cpu-independant & fully relocatable (completly pc-relative) code
  11. *
  12. * Once the Level 2 interrupt has been installed simply call 'ReadKeys' from
  13. * either your level 3 interrupt or your Vblank... 
  14. *
  15. * $Outputs:    d0.b = current key
  16. *        d1.b = keyboard qualifiers (see bit settings below)
  17. *
  18. * In this example if you press "CURSORLEFT" it will flash screen RED.. if
  19. * you continue to hold the key and then hold SHIFT as well it will flash both
  20. * RED and yellow.. a quick example of determining keyboard qualifiers!
  21. *******************************************************************************
  22. LSHIFT        =    1            * Bit: 0 (2^0)
  23. RSHIFT        =    2            * Bit: 1 (2^1)
  24. CAPS        =    4            * Bit: 2 (2^2)
  25. CTRL        =    8            * Bit: 3 (2^3)
  26. LALT        =    16            * Bit: 4 (2^4)
  27. RALT        =    32            * Bit: 5 (2^5)
  28. LAMIGA        =    64            * Bit: 6 (2^6)
  29. RAMIGA        =    128            * Bit: 7 (2^7)
  30.  
  31. CURSORUP    =    $4C            * for a complete list of the
  32. CURSORLEFT    =    $4F            * keys.. see RAWKEY codes..
  33.                         * in Hardware Ref.Manual or
  34.                         * work them out for yourself!
  35.  
  36. test:        move.l    4.w,a6
  37.         jsr    -132(a6)        * forbid() - disable multitasking
  38.  
  39.         lea    Level2(pc),a1        * our new interrupt
  40.  
  41.         move.l    _VBR(pc),a4        * get vectorbase
  42.         lea    OldLev2(pc),a0        * our level2 save
  43.         move.l    $68(a4),(a0)        * save os level2
  44.         move.l    a1,$68(a4)        * install new keyboard level2
  45.  
  46. *-------------- main loop
  47.  
  48. main        cmp.b    #255,$dff006        * wait vblank
  49.         bne.s    main
  50.  
  51. DoKeys        bsr    ReadKeys        * Returns: d0.b = key code
  52.                         *     : d1.b = qualifiers
  53.         cmp.b    #CURSORLEFT,d0
  54.         bne.s    no_more
  55.  
  56.         cmp.b    #LSHIFT,d1
  57.         bne.s    no_shift
  58.         move.w    #$ff0,$dff180        * screen yellow..
  59. no_shift    move.w    #$f00,$dff180        * screen red..
  60.  
  61. no_more        cmp.b    #CURSORUP,d0
  62.         bne.s    no_less
  63.  
  64.         move.w    #$00f,$dff180        * screen blue...
  65. no_less
  66.         btst    #6,$BFE001.l        * check leftmouse
  67.         bne.s    main            * if pressed... exit..
  68.  
  69. *-------------- exit
  70.  
  71.         move.l    _VBR(pc),a4        * get vectorbase
  72.         move.l    OldLev2(pc),$68(a4)    * restore os level2
  73.  
  74.         move.l    4.w,a6
  75.         jsr    -138(a6)        * permit() - restore multitask
  76.  
  77.         lea    kb_temp(pc),a1
  78.         moveq    #0,d0
  79.         move.b    kb.Qualifiers(a1),d0
  80.         move.b    kb.key(a1),d1
  81.         rts    
  82.  
  83. _VBR:        dc.l    0            * current vectorbase
  84. OldLev2        dc.l    0
  85.  
  86.  
  87.  
  88.         rsreset
  89. kb.qualifiers:    rs.b    1
  90. kb.keytmp:    rs.b    1
  91. kb.lastkeytmp:    rs.b    1
  92. kb.keydelaytmp:    rs.b    1
  93. kb.repspeedtmp:    rs.b    1
  94. kb.key:        rs.b    1
  95. kb.reserved:    rs.w    1
  96. kb.sizeof    rs.b    0
  97.         rsreset
  98.  
  99. Level2        movem.l    d0-d7/a0-a6,-(sp)    * preserve irq reg`s..
  100.  
  101.         lea    $DFF000.l,a6        * hardware base..
  102.         move.w    $1E(a6),d0        * intreqr
  103.         and.w    #8,d0            * level 2 request ?
  104.         beq.s    Exit_Lev2
  105.  
  106.         btst    #3,$BFED01.l        * from keyboard?
  107.         beq.s    _Exit_Lev2
  108.  
  109.         lea    kb_temp(pc),a1
  110.         move.b    $BFEC01,d0        * get key
  111.         bset    #6,$BFEE01        * start ciaa
  112.         not.w    d0
  113.         ror.b    #1,d0
  114.         bsr.s    GetKeycodes
  115.  
  116.         lea    $dff006,a1
  117.         moveq    #4-1,d2
  118. key6:        move.b    (a1),d3
  119. key1:        cmp.b    (a1),d3            * wait 4 rasters... before ciaa
  120.         beq.b    key1            * stop.. ack`ing keyboard
  121.         dbf    d2,key6
  122.  
  123.         bclr    #6,$BFEE01.l        * stop ciaa - acknowlege kb
  124.  
  125. _Exit_Lev2    move.w    #8,$9C(a6)        * clear irq bit..
  126. Exit_Lev2    movem.l    (sp)+,d0-d7/a0-a6    * restore irq reg`s..
  127.  
  128.         nop        * NB: these nop`s are here for 040/060
  129.         nop        * cache compatibility! you should do
  130.         rte        * the same for any other hardware irq`s
  131.         nop        * like a Level3 that you setup to make
  132.         nop        * sure your code works on MC680x0!
  133.  
  134.         
  135. GetKeycodes    lea    Qualifier_Table(pc),a0
  136.         moveq    #7,d7
  137.         moveq    #0,d2
  138.         move.b    (a1),d3            ;kb.Qualifiers(a1),d3
  139. check_qual1    move.b    (a0)+,d1
  140.         cmp.b    d0,d1
  141.         bne.s    checkqual2
  142.         bset    d2,d3
  143.         move.b    d3,(a1)            ;kb.Qualifiers(a1)
  144.         rts
  145. checkqual2    add.w    #$80,d1
  146.         cmp.b    d0,d1
  147.         bne.s    checkqual4
  148.         bclr    d2,d3
  149. checkqual3    move.b    d3,(a1)            ;kb.Qualifiers(a1)
  150.         rts
  151. checkqual4    addq.b    #1,d2
  152.         dbra    d7,check_qual1
  153.         tst.b    d0
  154.         bpl.s    KeyOk
  155.         move.b    d0,d1
  156.         sub.b    #$80,d1
  157.         cmp.b    kb.KeyTMP(a1),d1
  158.         beq.s    KeyOk
  159.         rts
  160. KeyOk        move.b    d0,kb.KeyTMP(a1)
  161.         rts
  162.  
  163.  
  164.         cnop    0,4
  165. ReadKeys    lea    kb_temp(pc),a1
  166.         moveq    #0,d0
  167.         move.b    kb.KeyTMP(a1),d0
  168.         cmp.b    kb.LastKeyTMP(a1),d0
  169.         beq.s    Repeat
  170.         move.b    d0,kb.LastKeyTMP(a1)
  171.         sf.b    kb.KeyDelayTMP(a1)
  172.         bra.s    DoKey3
  173. Repeat        tst.b    kb.KeyDelayTMP(a1)
  174.         beq.s    DoKey
  175.         subq.b    #1,kb.KeyDelayTMP(a1)
  176.         bra.s    No_Key
  177. DoKey        tst.b    kb.RepSpeedTMP(a1)
  178.         beq.s    DoKey2
  179.         subq.b    #1,kb.RepSpeedTMP(a1)
  180.         bra.s    No_Key
  181. DoKey2        sf.b    kb.RepSpeedTMP(a1)
  182. DoKey3        tst.b    d0
  183.         bpl.s    DoKey4
  184. No_Key        st.b    d0
  185. DoKey4        move.b    d0,kb.KEY(a1)        * d0.b = keycode..
  186.         move.b    (a1),d1            ;kb.Qualifiers(a1),d1    * d1.b = qualifiers..
  187.         rts
  188.  
  189. kb_temp:    ds.b    kb.sizeof
  190. Qualifier_Table    dc.b    "`abcdefg"
  191.  
  192.